%{
#include <stdio.h>
#include <stdlib.h>
%}

%token PROGRAM
%token CONST 
%token FUNCTION 
%token PROCEDURE
%token INICIO
%token END 
%token VAR 
%token ARRAY
%token RECORD
%token ENUM
%token ASSIGN
%token IF
%token THEN
%token ELSE
%token ENDIF
%token FOR
%token TO
%token STEP
%token DO
%token WHILE
%token WRITE
%token READ
%token REPEAT
%token UNTIL
%token CASE
%token OF
  
%token BOOLEAN
%token OP_BOOLEAN
%token STRING
%token CHAR
%token INTEIRO
%token REAL
  
%token ADICAO
%token SUBTRACAO
%token DIVISAO
%token MULTIPLICACAO
%token MOD 
%token DIV
  
%token DOISPONTOS
%token PONTO
%token PONTOEVIRGULA
%token ABRE_COL
  
%token FECHA_COL
%token ABRE_PAR 
%token FECHA_PAR 
  
%token RELOP
%token LT 
%token LE 
%token EQ 
%token NE 
%token GT 
%token GE 
%token ID
  
%token VIRGULA
%token OP_ARITMETICO

%token NOT
%token AND
%token OR
%token TRUE
%token FALSE

%left OR AND
%left ADICAO SUBTRACAO
%left MULTIPLICACAO DIVISAO DIV
%left MOD
%left NOT
%%

start : programa

programa : PROGRAM ID PONTOEVIRGULA componentes INICIO lista_stmts END PONTO
	| PROGRAM ID PONTOEVIRGULA INICIO lista_stmts END PONTO  
	;

lista_procedure : procedure
	| lista_procedure procedure
	;

procedure : PROCEDURE ID ABRE_PAR id_list FECHA_PAR PONTOEVIRGULA var_section INICIO lista_stmts END PONTOEVIRGULA
	;

id_list : ID
	| ID VIRGULA id_list
	;

var_section : VAR id_list PONTOEVIRGULA
	;

componentes : ID
	;

lista_stmts : ID
	;


/*
componentes : CONST
	| data_type
	| lista_procedure
	| lista_function
	| var_section
	;
*/
/*
data_type : array
	| record
	| enum_d
	;

array : ARRAY ABRE_COL id_list FECHA_COL
	;

record : RECORD ID INICIO id_list END
	;

enum_d : ENUM ID ASSIGN id_list
	;

lista_procedure : procedure
	| lista_procedure procedure
	;

lista_function : function
	| lista_function function
	;

function : FUNCTION ID ABRE_PAR id_list FECHA_PAR var_section INICIO stmts END PONTOEVIRGULA
	;

lista_stmts : stmts PONTOEVIRGULA
	| lista_stmts stmts PONTOEVIRGULA
	;

stmts : ID assign 
	| ID procedure_c
	| inst_if 
	| inst_for 
	| inst_while 
	| write 
	| read 
	| inst_case 
	| INICIO lista_stmts END 
	| REPEAT lista_stmts UNTIL expr
	;

assign : ASSIGN expr PONTOEVIRGULA
	;

procedure_c : ABRE_PAR id_list FECHA_PAR
	;

inst_if : IF expr THEN lista_stmts ELSE lista_stmts ENDIF
	| IF expr THEN lista_stmts ENDIF
	;

inst_for : FOR ID ASSIGN expr TO expr STEP expr DO lista_stmts
	| FOR ID ASSIGN expr TO expr DO lista_stmts
;

inst_while :
	WHILE expr DO lista_stmts
;

write :
	WRITE ABRE_PAR expr FECHA_PAR
;

read :
	READ ABRE_PAR id_list FECHA_PAR
;

inst_case :
	CASE expr OF option ELSE stmts
;

option : ID DOISPONTOS stmts
	| ID DOISPONTOS stmts PONTOEVIRGULA option
;

expr : expr ADICAO expr
	| expr SUBTRACAO expr
	| expr MULTIPLICACAO expr
	| expr DIVISAO expr
	| expr DIV expr
	| expr MOD expr
	| expr OR expr
	| expr AND expr
	| NOT expr
	| ABRE_PAR expr FECHA_PAR
	| ID PONTO ID
	| function_c
	| array_c
	;

function_c : ABRE_PAR id_list FECHA_PAR
	;

array_c : ABRE_COL ID FECHA_COL
;

procedure : PROCEDURE ID ABRE_PAR id_list FECHA_PAR PONTOEVIRGULA var_section INICIO stmts END PONTOEVIRGULA
	;

id_list : ID
	| ID id_list
	;

var_section : VAR ID PONTOEVIRGULA
	;

*/
%%

extern FILE *yyin;

main(){
	do {
		yyparse();
	} while(!feof(yyin));
}

yyerror(char *s){
	extern int yylineno;
	extern char* yytext;
	printf("\n Erro: %s \n\t%s on line %d \n",s,yytext,yylineno);
}	
